package com.xiwen.plugin.aspect;

import java.util.concurrent.*;

/**
 * @Author zhaozhiqiang
 * @Description 线程池
 * @Date 2021-1-8
 **/
public class ThreadPoolManager {
    private static ThreadPoolExecutor executor;// 线程执行者
    private int corePoolSize;// 核心线程数；每个手机的核心线程数可能不一样要动态计算
    private int maximumPoolSize;// 最大线程数量；当缓冲队列满的时候会放到最大线程数等待；在这里包含可核心线程数的任务
    private long keepAliveTime = 60;// 存活时间；最大线程池等待任务存活的时间
    private TimeUnit unit = TimeUnit.SECONDS;// 存活时间的时间单位
    private static ThreadPoolManager mInstance;


    /**
     * 单列设计模式
     *
     * @return
     */
    public static ThreadPoolManager getmInstance() {
        synchronized (ThreadPoolManager.class) {
            if (mInstance == null) {
                mInstance = new ThreadPoolManager();
            }
            return mInstance;
        }
    }

    // 下面是定制性非常强的方法
    private ThreadPoolManager() {
        // 核心线程池计算的法则=当前设置可用处理器核心数*2+1
        corePoolSize = Runtime.getRuntime().availableProcessors() * 2 + 1;
        maximumPoolSize = corePoolSize;// 必须赋值否则非法参数异常
        executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
                keepAliveTime, unit,
                // 缓冲队列，当缓冲队列满的时候会放到最大线程数等待;Thread线程消耗系统资源会内存溢出，而Runnable是线程执行的对象不会消耗系统资源
				/*几种工作阻塞队列
			    ArrayBlockingQueue（用数组实现的有界阻塞队列，按FIFO排序量）
			    LinkedBlockingQueue（基于链表结构的阻塞队列，按FIFO排序任务，容量可以选择进行设置，不设置的话，将是一个无边界的阻塞队列）
			    DelayQueue（一个任务定时周期的延迟执行的队列）
			    PriorityBlockingQueue（具有优先级的无界阻塞队列）
			    SynchronousQueue（一个不存储元素的阻塞队列，每个插入操作必须等到另一个线程调用移除操作，否则插入操作一直处于阻塞状*/
                new SynchronousQueue<Runnable>(),
                Executors.defaultThreadFactory(),// 创建线程的工厂类
				/*四种拒绝策略
			    AbortPolicy(抛出一个异常，默认的)
			    DiscardPolicy(直接丢弃任务)
			    DiscardOldestPolicy（丢弃队列里最老的任务，将当前这个任务继续提交给线程池）
			    CallerRunsPolicy（交给线程池调用所在的线程*/
                new ThreadPoolExecutor.CallerRunsPolicy()// 当最大线程数超出的时候，则拒绝执行
        );
    }

    /**
     * 销毁核心线程
     * @param flag true 销毁，false不销毁
     * @param pool 线程池对象
     */
    public void idDestroy(boolean flag, ThreadPoolExecutor pool) {
        pool.allowCoreThreadTimeOut(flag);//核心线程超过keepAliveTime(60s)也会被销毁
    }

    /**
     * 往线程池中添加任务
     */
    public void execute(Runnable runnable) {
        // Thread线程消耗系统资源会内存溢出，而Runnable是线程执行的对象不会消耗系统资源
        if (runnable != null) {
            executor.execute(runnable);
        }
    }

    public static void main(String[] args) {


    }



    /**
     * 往线程池中添加任务
     */
    public Object submit(Callable<Object> callback) {
        // Thread线程消耗系统资源会内存溢出，而Runnable是线程执行的对象不会消耗系统资源
        Object object = null;
        if (callback != null) {
            try {
                FutureTask<Object> futureTask = new FutureTask<Object>(callback);
                executor.submit(futureTask);
                object = futureTask.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            } finally {
                //移除当前任务
                boolean contains = contains(callback);
                if (contains) {
                    remove(callback);
                }
            }
        }
        return object;
    }


    /**
     * 往线程池中移除任务
     */
    public void remove(Runnable runnable) {
        // Thread线程消耗系统资源会内存溢出，而Runnable是线程执行的对象不会消耗系统资源
        if (runnable != null) {
            executor.remove(runnable);
        }
    }

    /**
     * 往线程池中移除任务
     */
    public void remove(Callable runnable) {
        // Thread线程消耗系统资源会内存溢出，而Runnable是线程执行的对象不会消耗系统资源
        if (runnable != null) {
            executor.remove((Runnable) runnable);
        }
    }

    /**
     * 线程池中是否包含某个任务
     */
    public synchronized static boolean contains(Callable run) {
        if (executor != null
                && (!executor.isShutdown() || executor.isTerminating())) {// Terminating终结了
            return executor.getQueue().contains(run);
        } else {
            return false;
        }
    }

    /**
     * 线程池中是否包含某个任务
     */
    public synchronized static boolean contains(Runnable run) {
        if (executor != null
                && (!executor.isShutdown() || executor.isTerminating())) {// Terminating终结了
            return executor.getQueue().contains(run);
        } else {
            return false;
        }
    }

    /**
     * 不接受新的任务，也不执行队列中的任务，打断正在执行的work线程
     */
    public synchronized static void shutdownNow() {
        if (executor != null
                && (!executor.isShutdown() || executor.isTerminating())) {
            executor.shutdownNow();
        }
    }

    /**
     * 不接受新的任务，但会执行队列中的任务，执行钩子函数onShutDown()
     */
    public synchronized static void shutdown() {
        if (executor != null
                && (!executor.isShutdown() || executor.isTerminating())) {
            executor.shutdown();
        }
    }

}